<template>
	<div
		ref="alert"
		:class="[
			'app-alert',
			enableScroll
				? showStyle == 'MARQUEE2'
					? 'enable-scroll vertical-scroll'
					: 'enable-scroll horizontal-scroll'
				: '',
		]"
	>
		<template v-if="items && items.length > 0">
			<template v-for="(item, index) in items">
				<template v-if="item.hasContent && !Object.is('POPUP', item.position)">
					<a-alert
						v-show="item.showState"
						:key="index"
						:type="item.type"
						:closable="item.closeable"
						:class="[
							'alert-item',
							`item-index-${index}`,
							curIndex === index ? 'active' : '',
						]"
						@close="alertClose(item)"
					>
						<template #message>
							<div class="item-title">{{ item.title }}</div>
							<span
								v-if="item.messageType == 'HTML'"
								v-html="item.content"
							></span>
							<span v-else>{{ item.content }}</span>
						</template>
					</a-alert>
				</template>
			</template>
		</template>
	</div>
</template>
<script setup lang="ts">
import { alertProps } from './alert';
import { message } from 'ant-design-vue';
import { Ref } from 'vue';

const props = defineProps(alertProps);

let alert: Ref<HTMLElement | null> = ref(null);

/**
 * 开启滚动
 */
const enableScroll = ref(false);

/**
 * 视图消息对象
 */
const items: Ref<any[]> = ref([]);

/**
 * 当前展示消息下标（开启滚动时启用）
 */
const curIndex = ref(0);

/**
 * 定时器对象（开启滚动时启用）
 */
let timer: any = null;

/**
 * 定时器执行间隔（开启滚动时启用）
 */
const delayTime = 3000;

/**
 * 视图消息模型集合
 */
const messageDetails: Ref<any[]> = ref([]);

/**
 * 消息类型对应背景颜色集合
 */
const bgColorMap: any = {
	success: '#f0f9eb',
	info: '#f4f4f5',
	warning: '#fdf6ec',
	error: '#fef0f0',
};

/**
 * 根据位置过滤视图消息数组
 *
 * @param position 视图消息位置
 * @memberof ViewMessageService
 */
const getViewMsgDetails = (position: string, viewMessageDetails: any[]) => {
	if (!position) {
		return viewMessageDetails;
	}
	if (position == 'TOP') {
		return viewMessageDetails.filter((detail: any) => {
			return detail.position == 'TOP' || detail.position == 'POPUP';
		});
	} else {
		return viewMessageDetails.filter((detail: any) => {
			return detail.position == position;
		});
	}
};

/**
 * 获取当前激活视图消息项（开启滚动时有效）
 */
const getActiveItem = () => {
	const showItems = items.value.filter((item: any) => item.showState);
	let tempItems: any = [];
	if (curIndex.value < items.value.length - 1) {
		tempItems = items.value.slice(curIndex.value + 1, items.value.length);
	} else {
		tempItems = [...showItems];
	}
	const index = getActiveItemIndex(tempItems);
	//  无显示项
	if (index == -1 && showItems.length == 0) {
		noItemsShow();
	} else if (index == -1) {
		//  获取第一个激活项
		curIndex.value = items.value.findIndex((_item: any) =>
			Object.is(_item, showItems[0])
		);
	} else {
		curIndex.value = index;
	}
	if (index != -1) {
		handleContainerBgColorChange();
	}
};

/**
 * 视图消息关闭
 */
const alertClose = (data: any) => {
	data.showState = false;
	if (enableScroll.value && data.position !== 'POPUP') {
		getActiveItem();
		initScroll();
	}
	if (data.customClass) {
		let tempArr: any[] = data.customClass.toString().split(',');
		if (tempArr && tempArr.length > 0) {
			if (Object.is('1', tempArr[1])) {
				const tag = props.viewName + '_' + props.infoGroup + '_' + tempArr[0];
				localStorage.setItem(tag, data.customClass);
			}
		}
	}
	if (data.removeMode && data.removeMode == 1) {
		const tag = props.viewName + '_' + props.infoGroup + '_' + data.codeName;
		localStorage.setItem(tag, data.codeName);
	}
};

/**
 * 消息类型对应背景颜色集合
 */
const handleItemOption = (detail: any) => {
	//  是否存在内容
	detail.hasContent = true;
	if (!detail.title && !detail.content) {
		detail.hasContent = false;
	}
	//  关闭模式
	detail.closeable = detail.enableRemove;
	//  类型
	switch (detail.type) {
		case 'WARN':
			detail.type = 'warning';
			break;
		case 'SUCCESS':
			detail.type = 'success';
			break;
		case 'ERROR':
			detail.type = 'error';
			break;
		default:
			detail.type = 'info';
			break;
	}
};

/**
 * 处理数据关闭模式
 */
const handleItemCloseMode = (data: any) => {
	let flag = true;
	data.showState = true;
	if (data.removeMode || data.removeMode == 0) {
		if (data.removeMode == 1) {
			const tag = props.viewName + '_' + props.infoGroup + '_' + data.codeName;
			const codeName = localStorage.getItem(tag);
			if (codeName) {
				data.showState = false;
				flag = false;
			}
		}
		if (data.removeMode == 0) {
			data.closeable = false;
		}
	}
	return flag;
};

/**
 * 处理数据显示位置
 */
const handleItemPosition = (data: any, flag: boolean) => {
	if (data.position) {
		if (flag && Object.is('POPUP', data.position)) {
			data.showState = false;
			const type: 'info' | 'success' | 'error' | 'warning' = data.type;
			if (Object.is('HTML', data.messageType)) {
				setTimeout(() => {
					message[type]({
						class: data.codeName + ',' + data.removeMode,
						content: h('div', {}, [
							h('p', data.title),
							h('p', { domProps: { innerHTML: data.content } }),
						]),
						onClose: () => alertClose(data),
					});
				}, 0);
			} else {
				setTimeout(() => {
					message[type]({
						class: data.codeName + ',' + data.removeMode,
						content: h('div', {}, [h('p', data.title), h('p', data.content)]),
						onClose: () => alertClose(data),
					});
				}, 0);
			}
		}
	}
};

const initOptions = () => {
	if (props.showStyle == 'MARQUEE' || props.showStyle == 'MARQUEE2') {
		enableScroll.value = true;
	}
	if (messageDetails.value.length > 0) {
		messageDetails.value.forEach((detail: any) => {
			handleItemOption(detail);
			let flag = handleItemCloseMode(detail);
			handleItemPosition(detail, flag);
			items.value.push(detail);
		});
		//  开启滚动时获取激活视图消息项
		if (enableScroll.value) {
			getActiveItem();
		}
	}
};

/**
 * 删除定时器
 *
 * @memberof AppAlert
 */
const removeInterval = () => {
	if (timer) {
		clearInterval(timer);
		timer = null;
	}
};

/**
 * 初始化滚动逻辑，设置定时器
 */
const initScroll = () => {
	removeInterval();
	timer = setInterval(() => {
		getActiveItem();
	}, delayTime);
};

/**
 * 无视图消息展示（开启滚动时有效）
 *
 * @description 无视图消息展示时，隐藏消息容器，删除定时器
 * @memberof AppAlert
 */
const noItemsShow = () => {
	if (alert.value) {
		alert.value.style.display = 'none';
	}
	removeInterval();
};

/**
 * 处理视图消息容器背景颜色变化（开启滚动时有效）
 */
const handleContainerBgColorChange = () => {
	const item = items.value[curIndex.value];
	if (alert.value && item) {
		const oldBgColor = getComputedStyle(alert.value).getPropertyValue(
			'--new-message-bg-color'
		);
		const newBgColor = bgColorMap[item.type];
		alert.value.style.setProperty('--old-message-bg-color', oldBgColor);
		alert.value.style.setProperty('--new-message-bg-color', newBgColor);
	}
};

/**
 * 获取当前激活视图消息项下标（开启滚动时有效）
 *
 * @description 获取当前激活视图消息项对应items中的下标，没有时返回-1
 */
const getActiveItemIndex = (tempItems: any[]) => {
	if (tempItems.length == 0) {
		return -1;
	}
	let tempItem: any = tempItems.find((item: any) => {
		return item.showState;
	});
	if (!tempItem) {
		return -1;
	}
	return items.value.findIndex((_item: any) => {
		return Object.is(tempItem, _item);
	});
};

watch(
	() => props.viewMsgs,
	(newVal, oldVal) => {
		if (newVal !== oldVal) {
			messageDetails.value = getViewMsgDetails(props.position, newVal);
			initOptions();
			if (enableScroll.value) {
				initScroll();
			}
		}
	},
	{ deep: true, immediate: true }
);

onMounted(() => {});

onUnmounted(() => {
	removeInterval();
});
</script>
